"""
日历组件数据模型

包含所有与日历和日程相关的数据模型：
- Calendar: 日历基本信息
- Event: 日程基本信息
- EventRecurrence: 重复规则
- EventReminder: 提醒设置
- EventParticipant: 参与者信息
- EventTag: 标签管理
- CalendarShare: 日历分享
"""

from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, Enum, Table, ForeignKey
from sqlalchemy.dialects.mysql import JSON
from sqlalchemy.orm import relationship
from datetime import datetime
import enum
from db.session import Base
from db.models import BaseTable


class CalendarVisibility(enum.Enum):
    """日历可见性枚举"""
    PRIVATE = "private"    # 私有日历
    PUBLIC = "public"      # 公开日历
    SHARED = "shared"      # 分享日历


class EventStatus(enum.Enum):
    """日程状态枚举"""
    CONFIRMED = "confirmed"    # 已确认
    TENTATIVE = "tentative"    # 暂定
    CANCELLED = "cancelled"    # 已取消


class EventPriority(enum.Enum):
    """日程优先级枚举"""
    LOW = "low"        # 低优先级
    MEDIUM = "medium"  # 中优先级
    HIGH = "high"      # 高优先级


class RepeatType(enum.Enum):
    """重复类型枚举"""
    DAILY = "daily"        # 每日重复
    WEEKLY = "weekly"      # 每周重复
    MONTHLY = "monthly"    # 每月重复
    YEARLY = "yearly"      # 每年重复


class ReminderType(enum.Enum):
    """提醒类型枚举"""
    POPUP = "popup"        # 弹窗提醒
    EMAIL = "email"        # 邮件提醒
    SMS = "sms"           # 短信提醒
    NOTIFICATION = "notification"  # 应用内通知


class SharePermission(enum.Enum):
    """分享权限枚举"""
    VIEW = "view"         # 查看权限
    EDIT = "edit"         # 编辑权限
    MANAGE = "manage"     # 管理权限


class ParticipantStatus(enum.Enum):
    """参与者状态枚举"""
    NEEDS_ACTION = "needs_action"  # 需要操作
    ACCEPTED = "accepted"          # 已接受
    DECLINED = "declined"          # 已拒绝
    TENTATIVE = "tentative"        # 暂定


# 日程和标签的多对多关系表
event_tag_table = Table(
    'event_tag',
    Base.metadata,
    Column('event_id', Integer, primary_key=True),
    Column('tag_id', Integer, primary_key=True),
    extend_existing=True
)


class Calendar(BaseTable):
    """
    日历模型
    
    存储日历的基本信息，包括：
    - 基本信息：名称、描述、颜色
    - 权限设置：可见性、默认权限
    - 关联关系：所有者、分享、日程
    """
    __tablename__ = 'calendar'
    __table_args__ = {"extend_existing": True}
    
    # 基本信息
    name = Column(String(100), nullable=False, comment="日历名称")
    description = Column(Text, nullable=True, comment="日历描述")
    color = Column(String(7), nullable=False, default="#007bff", comment="日历颜色")
    timezone = Column(String(50), nullable=False, default="UTC", comment="时区")
    
    # 权限设置
    visibility = Column(Enum(CalendarVisibility), nullable=False, 
                       default=CalendarVisibility.PRIVATE, comment="可见性")
    default_permission = Column(Enum(SharePermission), nullable=False,
                               default=SharePermission.VIEW, comment="默认权限")
    
    # 关联信息
    owner_id = Column(Integer, nullable=False, comment="所有者ID")
    is_default = Column(Boolean, nullable=False, default=False, comment="是否为默认日历")


class Event(BaseTable):
    """
    日程模型
    
    存储日程的基本信息，包括：
    - 基本信息：标题、描述、位置
    - 时间信息：开始时间、结束时间、全天事件
    - 状态信息：状态、优先级、可见性
    - 关联关系：日历、重复规则、提醒、参与者、标签
    """
    __tablename__ = 'event'
    __table_args__ = {"extend_existing": True}
    
    # 基本信息
    title = Column(String(200), nullable=False, comment="日程标题")
    description = Column(Text, nullable=True, comment="日程描述")
    location = Column(String(200), nullable=True, comment="地点")
    url = Column(String(500), nullable=True, comment="相关链接")
    
    # 时间信息
    start_time = Column(DateTime, nullable=False, comment="开始时间")
    end_time = Column(DateTime, nullable=False, comment="结束时间")
    all_day = Column(Boolean, nullable=False, default=False, comment="是否为全天事件")
    timezone = Column(String(50), nullable=False, default="UTC", comment="时区")
    
    # 状态信息
    status = Column(Enum(EventStatus), nullable=False, default=EventStatus.CONFIRMED, comment="状态")
    priority = Column(Enum(EventPriority), nullable=False, default=EventPriority.MEDIUM, comment="优先级")
    visibility = Column(Enum(CalendarVisibility), nullable=False, 
                       default=CalendarVisibility.PRIVATE, comment="可见性")
    
    # 附加信息
    busy = Column(Boolean, nullable=False, default=True, comment="是否显示为忙碌")
    transparent = Column(Boolean, nullable=False, default=False, comment="是否透明")
    
    # 关联信息
    calendar_id = Column(Integer, nullable=False, comment="日历ID")
    creator_id = Column(Integer, nullable=False, comment="创建者ID")
    parent_event_id = Column(Integer, nullable=True, comment="父日程ID")
    
    # 扩展信息（JSON格式）
    extended_properties = Column(JSON, nullable=True, comment="扩展属性")


class EventRecurrence(BaseTable):
    """
    重复规则模型
    
    存储日程的重复规则信息，包括：
    - 重复类型：每日、每周、每月、每年
    - 重复间隔：每隔多少时间单位重复
    - 重复条件：具体的重复规则设置
    - 结束条件：结束日期或重复次数
    """
    __tablename__ = 'event_recurrence'
    
    # 重复基本信息
    event_id = Column(Integer,  nullable=False, comment="日程ID")
    repeat_type = Column(Enum(RepeatType), nullable=False, comment="重复类型")
    interval = Column(Integer, nullable=False, default=1, comment="重复间隔")
    
    # 重复条件
    repeat_days = Column(JSON, nullable=True, comment="重复星期几（用于周重复）")
    repeat_month_day = Column(Integer, nullable=True, comment="重复日期（用于月重复）")
    repeat_month = Column(Integer, nullable=True, comment="重复月份（用于年重复）")
    repeat_week = Column(Integer, nullable=True, comment="重复第几周（用于月重复）")
    repeat_week_day = Column(Integer, nullable=True, comment="重复星期几（用于月重复）")
    
    # 结束条件
    end_date = Column(DateTime, nullable=True, comment="结束日期")
    end_count = Column(Integer, nullable=True, comment="重复次数")
    
    # 例外日期
    exception_dates = Column(JSON, nullable=True, comment="例外日期列表")


class EventReminder(BaseTable):
    """
    提醒设置模型
    
    存储日程的提醒设置，包括：
    - 提醒类型：弹窗、邮件、短信、应用内通知
    - 提醒时间：提前多少时间提醒
    - 提醒状态：是否已发送、是否已确认
    """
    __tablename__ = 'event_reminder'
    
    # 提醒基本信息
    event_id = Column(Integer,  nullable=False, comment="日程ID")
    reminder_type = Column(Enum(ReminderType), nullable=False, comment="提醒类型")
    minutes_before = Column(Integer, nullable=False, comment="提前多少分钟提醒")
    
    # 提醒状态
    is_sent = Column(Boolean, nullable=False, default=False, comment="是否已发送")
    sent_at = Column(DateTime, nullable=True, comment="发送时间")
    is_confirmed = Column(Boolean, nullable=False, default=False, comment="是否已确认")
    confirmed_at = Column(DateTime, nullable=True, comment="确认时间")
    
    # 提醒内容
    message = Column(Text, nullable=True, comment="提醒消息")


class EventParticipant(BaseTable):
    """
    参与者模型
    
    存储日程的参与者信息，包括：
    - 参与者：用户ID、邮箱、姓名
    - 参与状态：需要操作、已接受、已拒绝、暂定
    - 权限设置：查看、编辑、管理
    """
    __tablename__ = 'event_participant'
    
    # 参与者信息
    event_id = Column(Integer,  nullable=False, comment="日程ID")
    user_id = Column(Integer,  nullable=True, comment="用户ID")
    email = Column(String(100), nullable=True, comment="邮箱地址")
    name = Column(String(100), nullable=True, comment="姓名")
    
    # 参与状态
    status = Column(Enum(ParticipantStatus), nullable=False, 
                   default=ParticipantStatus.NEEDS_ACTION, comment="参与状态")
    permission = Column(Enum(SharePermission), nullable=False,
                       default=SharePermission.VIEW, comment="权限")
    
    # 响应信息
    responded_at = Column(DateTime, nullable=True, comment="响应时间")
    response_message = Column(Text, nullable=True, comment="响应消息")
    
    # 通知设置
    notify_email = Column(Boolean, nullable=False, default=True, comment="邮件通知")
    notify_popup = Column(Boolean, nullable=False, default=True, comment="弹窗通知")


class EventTag(BaseTable):
    """
    标签模型
    
    存储日程标签信息，包括：
    - 标签基本信息：名称、颜色、描述
    - 使用统计：使用次数
    """
    __tablename__ = 'event_tag'
    __table_args__ = {"extend_existing": True}
    
    # 标签信息
    name = Column(String(50), nullable=False, comment="标签名称")
    color = Column(String(7), nullable=False, default="#6c757d", comment="标签颜色")
    description = Column(Text, nullable=True, comment="标签描述")
    
    # 使用统计
    usage_count = Column(Integer, nullable=False, default=0, comment="使用次数")
    
    # 关联信息
    user_id = Column(Integer, nullable=False, comment="创建者ID")


class CalendarShare(BaseTable):
    """
    日历分享模型
    
    存储日历分享信息，包括：
    - 分享信息：分享给谁、分享权限
    - 分享状态：是否已接受、分享时间
    """
    __tablename__ = 'calendar_share'
    
    # 分享信息
    calendar_id = Column(Integer,  nullable=False, comment="日历ID")
    shared_with_id = Column(Integer,  nullable=True, comment="分享给的用户ID")
    shared_with_email = Column(String(100), nullable=True, comment="分享给邮箱")
    
    # 权限设置
    permission = Column(Enum(SharePermission), nullable=False, 
                       default=SharePermission.VIEW, comment="分享权限")
    
    # 分享状态
    is_accepted = Column(Boolean, nullable=False, default=False, comment="是否已接受")
    accepted_at = Column(DateTime, nullable=True, comment="接受时间")
    
    

class EventComment(BaseTable):
    """
    日程评论模型
    
    存储日程评论信息，包括：
    - 评论内容：文本、附件
    - 评论信息：评论者、回复关系
    """
    __tablename__ = 'event_comment'
    
    # 评论内容
    event_id = Column(Integer,  nullable=False, comment="日程ID")
    user_id = Column(Integer,  nullable=False, comment="评论者ID")
    content = Column(Text, nullable=False, comment="评论内容")
    
    # 回复信息
    parent_comment_id = Column(Integer,  nullable=True, comment="父评论ID")
    
    # 附件信息
    attachments = Column(JSON, nullable=True, comment="附件信息")